home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / db / RCS / Db_LockDesc.c,v < prev    next >
Text File  |  1988-09-21  |  5KB  |  185 lines

  1. head     1.2;
  2. access   ;
  3. symbols  ;
  4. locks    ; strict;
  5. comment  @ * @;
  6.  
  7.  
  8. 1.2
  9. date     88.09.13.16.48.36;  author douglis;  state Exp;
  10. branches ;
  11. next     1.1;
  12.  
  13. 1.1
  14. date     88.08.14.15.08.10;  author douglis;  state Exp;
  15. branches ;
  16. next     ;
  17.  
  18.  
  19. desc
  20. @Procedure to lock a file descriptor, optionally polling or breaking
  21. the lock.
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @fixed some lint; added check for DB_LOCK_NONE lock type.
  28. @
  29. text
  30. @/* 
  31.  * Db_LockDesc.c --
  32.  *
  33.  *    Source code for the Db_LockDesc procedure.
  34.  *
  35.  * Copyright 1988 Regents of the University of California
  36.  * Permission to use, copy, modify, and distribute this
  37.  * software and its documentation for any purpose and without
  38.  * fee is hereby granted, provided that the above copyright
  39.  * notice appear in all copies.  The University of California
  40.  * makes no representations about the suitability of this
  41.  * software for any purpose.  It is provided "as is" without
  42.  * express or implied warranty.
  43.  */
  44.  
  45. #ifndef lint
  46. static char rcsid[] = "$Header: Db_LockDesc.c,v 1.1 88/08/14 15:08:10 douglis Exp $ SPRITE (Berkeley)";
  47. #endif not lint
  48.  
  49.  
  50. #include <db.h>
  51. #include "dbInt.h"
  52.  
  53.  
  54. /*
  55.  *----------------------------------------------------------------------
  56.  *
  57.  * Db_LockDesc --
  58.  *
  59.  *    Lock a file descriptor, polling if necessary, and potentially
  60.  *    breaking the lock if timeout occurs.
  61.  *
  62.  * Results:
  63.  *    If the file is locked, by hook or by crook,
  64.  *    0 is returned.  If the file is not successfully locked,
  65.  *    -1 indicates an error and errno gives a more specific error.
  66.  *
  67.  * Side effects:
  68.  *    None.
  69.  *
  70.  *----------------------------------------------------------------------
  71.  */
  72.  
  73. int
  74. Db_LockDesc(streamID, type, action)
  75.     int streamID;            /* file descriptor */
  76.     int type;                /* type of lock */
  77.     Db_LockHow action;        /* DB_LOCK_{POLL,BLOCK,NO_BLOCK,WAIT,NONE} */
  78. {
  79.     int delay;
  80.     int status;
  81.     int numTries;        /* Counter through the loop polling the lock */
  82.     int numRetries;        /* Counter through a loop retrying in the
  83.                  * event we break the lock and someone else
  84.                  * grabs it. */
  85.  
  86.     if (action == DB_LOCK_NONE) {
  87.     return(0);
  88.     }
  89.     if (action != DB_LOCK_WAIT) {
  90.     type |= LOCK_NB;
  91.     }
  92.     /*
  93.      * Try the lock, then loop.  This gets rid of an extraneous delay
  94.      * after the last unsuccessful lock try.
  95.      *
  96.      * If the lock call times out, return SUCCESS to keep the caller
  97.      * from aborting.
  98.      */
  99.     
  100.     status = flock(streamID, type);
  101.     if (status == -1) {
  102.     /*
  103.      * It is possible to get a sprite RPC_TIMEOUT condition, or other
  104.      * obscure error, which will map to EINVAL by default.  We're mostly
  105.      * interested in the EWOULDBLOCK condition, so if we get something
  106.      * we know is likely to be innocuous, return 0.  In particular,
  107.      * we don't want our caller to abort because the lock timed out, since
  108.      * it can wait for recovery.
  109.      */
  110.     if (errno == EINVAL) {
  111.         return(0);
  112.     } 
  113.     if ((errno != EWOULDBLOCK) || (action == DB_LOCK_NO_BLOCK)) {
  114.         return(-1);
  115.     }
  116.     } else {
  117.     return(0);
  118.     }
  119.  
  120.     for (numRetries = 0; numRetries < NUM_TRIES; numRetries++) {
  121.     delay = DELAY;
  122.     for (numTries = 0; numTries < NUM_TRIES; numTries++) {
  123.         (void) sleep(delay);
  124.         delay *= 2;
  125.         status = flock(streamID, type);
  126.         if (status == -1) {
  127.         if (errno = EINVAL) {
  128.             return(0);
  129.         }
  130.         if ((errno != EWOULDBLOCK) || (action == DB_LOCK_NO_BLOCK)) {
  131.             return(status);
  132.         }
  133.         }
  134.     }
  135.     if (action == DB_LOCK_POLL) {
  136.         return(ETIMEDOUT);
  137.     }
  138.     /*
  139.      * Break the lock if required.  Try to break an exclusive lock.  If
  140.      * that fails, and we were trying to get an exclusive lock, then try
  141.      * releasing a shared lock since that could have been the problem.
  142.      * Then try to get the lock again.
  143.      * Return EWOULDBLOCK if breaking the lock wasn't successful.
  144.      */
  145.     if (action == DB_LOCK_BREAK) {
  146.         status = flock(streamID, LOCK_EX | LOCK_NB | LOCK_UN);
  147.         if ((status != 0) && (type & LOCK_EX)) {
  148.         (void) flock(streamID, LOCK_SH | LOCK_NB | LOCK_UN);
  149.         }
  150.     }
  151.     status = flock(streamID, type);
  152.     if (status == 0) {
  153.         return(0);
  154.     } else if (errno != EWOULDBLOCK) {
  155.         return(status);
  156.     }
  157.     }
  158.     syslog(LOG_WARNING, "Db_LockDesc: unable to lock stream %d in %s mode",
  159.        streamID, (type & LOCK_EX) ? "exclusive" : "shared");
  160.     errno = EWOULDBLOCK;
  161.     return (-1);
  162. }
  163. @
  164.  
  165.  
  166. 1.1
  167. log
  168. @Initial revision
  169. @
  170. text
  171. @d17 1
  172. a17 1
  173. static char rcsid[] = "$Header: proto.c,v 1.2 88/03/11 08:39:08 ouster Exp $ SPRITE (Berkeley)";
  174. d48 1
  175. a48 1
  176.     Db_LockHow action;        /* DB_LOCK_{POLL,BLOCK,NO_BLOCK} */
  177. d50 1
  178. a50 1
  179.     unsigned int delay;
  180. d56 4
  181. a59 1
  182.     
  183. d87 2
  184. @
  185.